package com.lenovo.redission.redission.lock;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * Description: 分布式锁
 * <p>
 * Copyright: 天津联想协同科技有限公司
 * <p>
 *
 * @author 赵希坤 zhaoxk
 * @date 2021/5/31 4:37 下午
 */
public interface IDistributedLock {
    /**
     * 获取锁 立即返回
     *
     * @param lockKey    锁名称
     * @param expireTime 过期时间 若 != -1 就没有看门狗，会出现代码没有执行完，锁结束了
     * @param timeUnit   时间单位
     * @return true 加锁成功；反之失败
     * @throws InterruptedException
     */
    boolean tryLock(String lockKey, long expireTime, TimeUnit timeUnit) throws InterruptedException;

    /**
     * 获取锁 立即返回
     * 有看门狗，锁续命
     *
     * @param lockKey 锁名称
     * @return true 加锁成功；反之失败
     * @throws InterruptedException
     */
    default boolean tryLock(String lockKey) throws InterruptedException {
        return tryLock(lockKey, -1, TimeUnit.MILLISECONDS);
    }

    /**
     * 尝试获取锁 超时返回
     *
     * @param lockKey    锁名称
     * @param expireTime 过期时间 若 != -1 就没有看门狗，会出现代码没有执行完，锁结束了
     * @param waitTime   超时时间
     * @param timeUnit   时间单位
     * @return true 加锁成功；反之失败
     * @throws InterruptedException
     */
    boolean tryLockWait(String lockKey, long expireTime, long waitTime, TimeUnit timeUnit) throws InterruptedException;

    /**
     * 尝试获取锁 超时返回
     * 有看门狗，锁续命
     *
     * @param lockKey  锁名称
     * @param waitTime 超时时间
     * @param timeUnit 时间单位
     * @return true 加锁成功；反之失败
     * @throws InterruptedException
     */
    default boolean tryLockWait(String lockKey, long waitTime, TimeUnit timeUnit) throws InterruptedException {
        return tryLockWait(lockKey, -1L, waitTime, timeUnit);
    }

    /**
     * 以阻塞方式的获取锁
     *
     * @param lockKey 锁名称
     */
    void lock(String lockKey);

    /**
     * 解锁，不使用固定的字符串作为键的值，使用随机口令方式
     *
     * @param lockKey 锁名称
     * @return true 解锁成功；反之失败
     */
    void unlock(String lockKey);

}
